package kr.pe.johnkim.sendme.util;

import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;


public abstract class SwipeListViewActivity extends Activity {

	String TAG = "SwipeListViewActivity";
	
	private ListView list;
	private int REL_SWIPE_MIN_DISTANCE;			// 튕기기 최소 인식 거리 		: 시작점 ~ 끝점사이의 거리가 일정 거리 이상 되어야 됨
	private int REL_SWIPE_MAX_OFF_PATH;			// 튕기기 높이 제한선  		: 좌우로 튕기기 때문에 상하로 일정 범위가 넘어가면 튕기기로 인식되지 않음 
	private int REL_SWIPE_THRESHOLD_VELOCITY;	// 튕기기인식하는 최소 속도 	: 어느정도 이상의 속도로 튕겨야 인식됨
	/**
	 *
	 * @return ListView
	 */
	public abstract ListView getListView();

	/**
	 *
	 * @param isRight
	 * Swiping direction
	 * @param position
	 * which item position is swiped
	 */
	public abstract void getSwipeItem(boolean isRight, int position);

	/**
	 * For single tap/Click
	 *
	 * @param adapter
	 * @param position
	 */
	public abstract void onItemClickListener(ListAdapter adapter, int position);

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		DisplayMetrics dm = getResources().getDisplayMetrics();
		REL_SWIPE_MIN_DISTANCE = (int) (30.0f * dm.densityDpi / 160.0f + 0.5);		// (120.0f * dm.densityDpi / 160.0f + 0.5);	 // 180 -> 45
		REL_SWIPE_MAX_OFF_PATH = (int) (300.0f * dm.densityDpi / 160.0f + 0.5);		// (250.0f * dm.densityDpi / 160.0f + 0.5);
		REL_SWIPE_THRESHOLD_VELOCITY = (int) (100.0f * dm.densityDpi / 160.0f + 0.5);	// (200.0f * dm.densityDpi / 160.0f + 0.5); // 
		
	}

	@Override
	protected void onResume() {
		super.onResume();
		list = getListView();
		if (list == null) {
			new Throwable("Listview not set exception");
		}

		@SuppressWarnings("deprecation")
		final GestureDetector gestureDetector = new GestureDetector(
				new MyGestureDetector());

		View.OnTouchListener gestureListener = new View.OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				return gestureDetector.onTouchEvent(event);
			}
		};
		list.setOnTouchListener(gestureListener);

	}

	private void myOnItemClick(int position) {
		if (position < 0)
			return;
		onItemClickListener(list.getAdapter(), position);

	}

	class MyGestureDetector extends SimpleOnGestureListener {

		private int temp_position = -1;

		// Detect a single-click and call my own handler.
		@Override
		public boolean onSingleTapUp(MotionEvent e) {

			int pos = list.pointToPosition((int) e.getX(), (int) e.getY());
			myOnItemClick(pos);
			return true;
		}

		@Override
		public boolean onDown(MotionEvent e) {

			temp_position = list
					.pointToPosition((int) e.getX(), (int) e.getY());
			return super.onDown(e);
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {
			try{
				// 이중 레이아웃으로 e1이 null 
				if(e1==null){
					Log.d(TAG,"e1==null");
				}else{
//					Log.d(TAG,"e1.getX():"+e1.getX()+"//e2.getX():"+e2.getX());
					
					if (Math.abs(e1.getY() - e2.getY()) > REL_SWIPE_MAX_OFF_PATH){
//						Log.d(TAG,"Math.abs(e1.getY() - e2.getY()) > REL_SWIPE_MAX_OFF_PATH");
						return false;
					}
					if (e1.getX() - e2.getX() > REL_SWIPE_MIN_DISTANCE
							&& Math.abs(velocityX) > REL_SWIPE_THRESHOLD_VELOCITY) {
						int pos = list
								.pointToPosition((int) e1.getX(), (int) e2.getY());
						if (pos >= 0 && temp_position == pos){
							getSwipeItem(false, pos);
//							Log.d(TAG,"getSwipeItem(false, pos)");
						}else{
//							Log.d(TAG,"not(1) pos >= 0 && temp_position == pos");
						}
					} else if (e2.getX() - e1.getX() > REL_SWIPE_MIN_DISTANCE
							&& Math.abs(velocityX) > REL_SWIPE_THRESHOLD_VELOCITY) {
						int pos = list
								.pointToPosition((int) e1.getX(), (int) e2.getY());
						if (pos >= 0 && temp_position == pos){
							getSwipeItem(true, pos);
//							Log.d(TAG,"getSwipeItem(true, pos)");
						}else{
//							Log.d(TAG,"not(2) pos >= 0 && temp_position == pos// pos::"+pos);
						}
					}else{
//						Log.d(TAG,"e1.getX() - e2.getX():"+(e1.getX() - e2.getX())+"//REL_SWIPE_MIN_DISTANCE:"+REL_SWIPE_MIN_DISTANCE);
//						Log.d(TAG,"Math.abs(velocityX):"+(Math.abs(velocityX))+"//REL_SWIPE_THRESHOLD_VELOCITY:"+REL_SWIPE_THRESHOLD_VELOCITY);
//						Log.d(TAG,"what can i do");
					}
					
				}
				
			}catch(Exception e){
				e.printStackTrace();
			}
			return false;
		}

	}

}
// 에러나서 위의 소스 사용
//public abstract class SwipeListViewActivity extends Activity {
//
//	private ListView list;
//	private int REL_SWIPE_MIN_DISTANCE;			// 튕기기 최소 인식 거리 		: 시작점 ~ 끝점사이의 거리가 일정 거리 이상 되어야 됨
//	private int REL_SWIPE_MAX_OFF_PATH;			// 튕기기 높이 제한선  		: 좌우로 튕기기 때문에 상하로 일정 범위가 넘어가면 튕기기로 인식되지 않음 
//	private int REL_SWIPE_THRESHOLD_VELOCITY;	// 튕기기인식하는 최소 속도 	: 어느정도 이상의 속도로 튕겨야 인식됨
//
//	/**
//	 * 
//	 * @return ListView
//	 */
//	public abstract ListView getListView();
//
//	/**
//	 * 
//	 * @param isRight
//	 *            Swiping direction
//	 * @param position
//	 *            which item position is swiped
//	 */
//	public abstract void getSwipeItem(boolean isRight, int position);
//
//	/**
//	 * For single tap/Click
//	 * 
//	 * @param adapter
//	 * @param position
//	 */
//	public abstract void onItemClickListener(ListAdapter adapter, int position);
//	
//	/**
//	 * For long press
//	 * 
//	 * @param adapter
//	 * @param position
//	 */
//	public abstract void onItemLongClickListener(ListAdapter adapter, int position);
//	
//	
//	// 프래그먼트 모드에서는 실행되지 않음. 액티비티에서 호출됨.
//	@Override
//	public void onCreate(Bundle savedInstanceState){
//		super.onCreate(savedInstanceState);
////		View view = inflater.inflate(R.layout.fragment_main, null);
//		DisplayMetrics dm = getResources().getDisplayMetrics();
//		REL_SWIPE_MIN_DISTANCE = (int) (120.0f * dm.densityDpi / 160.0f + 0.5);
//		REL_SWIPE_MAX_OFF_PATH = (int) (250.0f * dm.densityDpi / 160.0f + 0.5);
//		REL_SWIPE_THRESHOLD_VELOCITY = (int) (200.0f * dm.densityDpi / 160.0f + 0.5);
//		
//		list = getListView();
//		if (list == null) {
//			new Throwable("Listview not set exception");
//		}
//
//		final GestureDetector gestureDetector = new GestureDetector(this, new MyGestureDetector());
//
//		View.OnTouchListener gestureListener = new View.OnTouchListener() {
//			public boolean onTouch(View v, MotionEvent event) {
//				return gestureDetector.onTouchEvent(event);
//			}
//		};
//		list.setOnTouchListener(gestureListener);
//		
//	}
//
//	// 프래그먼트 모드에서 실행됨	// 액티비티에서 실행 안되는 듯 함.
//	@Override
//	public void onResume() {
//		super.onResume();
//		DisplayMetrics dm = getResources().getDisplayMetrics();
//		REL_SWIPE_MIN_DISTANCE = (int) (120.0f * dm.densityDpi / 160.0f + 0.5);
//		REL_SWIPE_MAX_OFF_PATH = (int) (250.0f * dm.densityDpi / 160.0f + 0.5);
//		REL_SWIPE_THRESHOLD_VELOCITY = (int) (200.0f * dm.densityDpi / 160.0f + 0.5);
//		
//		list = getListView();
//		if (list == null) {
//			new Throwable("Listview not set exception");
//		}
//
//		final GestureDetector gestureDetector = new GestureDetector(this, new MyGestureDetector());
//
//		View.OnTouchListener gestureListener = new View.OnTouchListener() {
//			public boolean onTouch(View v, MotionEvent event) {
//				return gestureDetector.onTouchEvent(event);
//			}
//		};
//		list.setOnTouchListener(gestureListener);
//
//	}
//
//	private void myOnItemClick(int position) {
//		if (position < 0)
//			return;
//		onItemClickListener(list.getAdapter(), position);
//	}
//	private void myOnItemLongClick(int position){
//		if (position < 0)
//			return;
//		onItemLongClickListener(list.getAdapter(), position);
//	}
//
//	class MyGestureDetector extends SimpleOnGestureListener {
//
//		private int temp_position = -1;
//
//		// Detect a single-click and call my own handler.
//		@Override
//		public boolean onSingleTapUp(MotionEvent e) {
//			int pos = list.pointToPosition((int) e.getX(), (int) e.getY());
//			myOnItemClick(pos);
//			return true;
//		}
//
//		@Override
//		public void onLongPress(MotionEvent e){
//			int pos = list.pointToPosition((int) e.getX(), (int) e.getY());
//			myOnItemLongClick(pos);
//		}
//		
//		@Override
//		public boolean onDown(MotionEvent e) {
//			temp_position = list
//					.pointToPosition((int) e.getX(), (int) e.getY());
//			return super.onDown(e);
//		}
//
//		@Override
//		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
//				float velocityY) {
//			if (Math.abs(e1.getY() - e2.getY()) > REL_SWIPE_MAX_OFF_PATH){
//				return false;
//			}
//			if (e1.getX() - e2.getX() > REL_SWIPE_MIN_DISTANCE
//					&& Math.abs(velocityX) > REL_SWIPE_THRESHOLD_VELOCITY) {
//				int pos = list
//						.pointToPosition((int) e1.getX(), (int) e2.getY());
//
//				if (pos >= 0 && temp_position == pos){
//					getSwipeItem(false, pos);
//				}
//			} else if (e2.getX() - e1.getX() > REL_SWIPE_MIN_DISTANCE
//					&& Math.abs(velocityX) > REL_SWIPE_THRESHOLD_VELOCITY) {
//				int pos = list
//						.pointToPosition((int) e1.getX(), (int) e2.getY());
//				if (pos >= 0 && temp_position == pos){
//					getSwipeItem(true, pos);
//				}
//			}
//
//			return false;
//		}
//	}
//}
